package org.ctstudio.oa.duty.web;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.ctstudio.oa.duty.bean.Apply;
import org.ctstudio.oa.duty.bean.ApplyQuery;
import org.ctstudio.oa.duty.bean.DutySummary;
import org.ctstudio.oa.duty.bean.LeaveApply;
import org.ctstudio.oa.duty.bean.Staff;
import org.ctstudio.oa.duty.dao.LeaveMapper;
import org.ctstudio.oa.duty.service.DutyCalcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

/**
 * 请假业务
 * 
 * @author ct
 *
 */
@Controller
@RequestMapping("/leave")
public class LeaveController extends AbstractApplyController {
  @Autowired
  private LeaveMapper mapper;

  @Autowired
  private DutyCalcService service;

  @RequestMapping("/list.do")
  public String list(@ModelAttribute("query") ApplyQuery query, Model model) {
    long total = mapper.count(query);
    model.addAttribute("total", total);
    if (total > 0) {
      List<LeaveApply> list = mapper.query(query);
      model.addAttribute("list", list);
      model.addAttribute("staffMap", this.getStaffIdNameMap(list));
    }
    return "leave/list";
  }

  @ModelAttribute("leaveTypes")
  public Map<Long, String> getLeaveTypes() {
    return getSettings("leave.types");
  }

  @RequestMapping(value = "/apply.do", method = RequestMethod.GET)
  public String apply(Model model) {
    model.addAttribute("apply", new LeaveApply());
    return "leave/newOrEdit";
  }

  @RequestMapping(value = "/apply.do", method = RequestMethod.POST)
  public String onApply(@ModelAttribute("apply") LeaveApply apply, BindingResult result, Model model, RedirectAttributes redirect) {
    apply.setStatus(1);
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "uid", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "leaveType", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "fromDate", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "fromTime", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "toDate", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "toTime", "CANNOTEMPTY");
    ValidationUtils.rejectIfEmptyOrWhitespace(result, "reason", "CANNOTEMPTY");

    if (result.hasErrors()) {
      return "leave/newOrEdit";
    }

    service.calcLeaveTime(apply);
    if (apply.isNew()) {
      mapper.add(apply);
    } else {
      mapper.edit(apply);
    }
    return redirectList(apply, redirect);
  }

  private String redirectList(LeaveApply apply, RedirectAttributes redirect) {
    LocalDate date = apply.getFromDate();
    redirect.addAttribute("y", date.getYear());
    redirect.addAttribute("m", date.getMonthValue());
    redirect.addAttribute("d", date.getDayOfMonth());
    return "redirect:list.do?y={y}&m={m}&d={d}";
  }

  @RequestMapping(value = "/approve.do", method = RequestMethod.GET)
  public String approve(@RequestParam long id, Model model) {
    Apply apply = mapper.get(id);
    model.addAttribute("apply", apply);
    model.addAttribute("approval", apply);
    return "leave/approve";
  }

  @RequestMapping(value = "/approve.do", method = RequestMethod.POST)
  public String onApprove(@ModelAttribute("approval") Apply approval, BindingResult result, Model model, HttpServletRequest request,
      RedirectAttributes redirect) {
    String currentUid = request.getRemoteUser();
    LeaveApply apply = mapper.get(approval.getId());
    model.addAttribute("apply", apply);
    Staff staff = staffMapper.getByStaffId(apply.getUid());
    // 非主管提示权限不足
    if (currentUid == null | staff.getSupervisor() == null || !staff.getSupervisor().contains(currentUid)) {
      result.reject("NORIGHT");
      return "leave/approve";
    }
    approval.setApprover(request.getRemoteUser());
    mapper.approve(approval);
    return redirectList(apply, redirect);
  }

  @RequestMapping(value = "/totaltime/list.do")
  public String totalTimeList(@ModelAttribute("query") ApplyQuery query, Model model) {
    long total = mapper.countTotalTime(query);
    model.addAttribute("summaryType", query.getC());
    model.addAttribute("total", total);
    if (total > 0) {
      List<DutySummary> list = mapper.queryTotalTime(query);
      model.addAttribute("list", list);
      model.addAttribute("staffMap", this.getStaffIdNameMap(list));
    }
    return "leave/totaltimelist";
  }

  @RequestMapping(value = "/leftholiday/list.do")
  public String totalHolidayList(@ModelAttribute("query") ApplyQuery query, Model model) {
    long total = mapper.countHoliday(query);
    model.addAttribute("summaryType", query.getC());
    model.addAttribute("total", total);
    if (total > 0) {
      List<DutySummary> list = mapper.queryHoliday(query);
      model.addAttribute("list", list);
      model.addAttribute("staffMap", this.getStaffIdNameMap(list));
    }
    return "leave/leftholidaylist";
  }
}
